#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <poll.h>
#include <linux/input.h>
#include <fcntl.h>
#include <signal.h>

#include "vser.h"

int fd;

void sigio_handler(int signum, siginfo_t *siginfo, void *act)
{
    int ret;
    char buf[32];
    if (signum == SIGIO) {
        if (siginfo->si_band & POLLIN) {
            printf("FIFO is not empty\n");
            if ((ret = read(fd, buf, sizeof(buf))) != -1) {
                buf[ret] = '\0';
                puts(buf);
            }
        }
        if (siginfo->si_band & POLLOUT) {
            printf("FIFO is not full\n");
        }
    }
}

int main(int argc, char* argv[])
{
    int ret;
    int flag;
    struct sigaction act, oldact;

    // 1. 阻塞信号处理函数
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask, SIGIO);
    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = sigio_handler;
    if (sigaction(SIGIO, &act, &oldact) == -1)
            goto fail;

    // 2. 打开设备文件，设置文件属主
    fd = open("/dev/vser0", O_RDWR | O_NONBLOCK);
    if (fd == -1) {
        goto fail;
    }
    if (fcntl(fd, F_SETOWN, getpid()) == -1) {
        goto fail;
    }

    // 3. 设置设备资源可用时驱动向进程发送的信号
    if (fcntl(fd, F_SETSIG, SIGIO) == -1) {
        goto fail;
    }

    // 4. 设置文件的FASYNC标志，使能异步通知机制
    if (flag = fcntl(fd, F_GETFL) == -1) {
        goto fail;
    }
    if (fcntl(fd, F_SETFL, flag | FASYNC) == -1) {
        goto fail;
    }

    // 主函数休眠，等待驱动发送来的信号
    while (1) {
        sleep(1);
    }

fail:
    perror("aio test");
    exit(EXIT_FAILURE);
}